///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file formic/fqmc/fqmc.cpp
///
/// \brief   implementation for the fqmc program's driver function
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#include<cstdlib>
#include<iostream>
#include<ctime>

#include<formic/fqmc/fqmc.h>
#include<formic/fqmc/input.h>
#include<formic/fqmc/command.h>
#include<formic/fqmc/rest_gem_pow.h>
#include<formic/fqmc/all_pair_jast.h>
#include<formic/all_data.h>
#include<formic/command/command.h>
#include<formic/output/output.h>
#include<formic/random/random.h>
#include<formic/numeric/numeric.h>
#include<formic/timing/timing.h>
#include<formic/mpi/interface.h>
#include<formic/hf/hf.h>

///////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief   driver function for the fqmc program
///
/// \param[in]     argc     the argument count
/// \param[in]     argv     the command line arguments
///
/// \return the exit code
///
///////////////////////////////////////////////////////////////////////////////////////////////////

int formic::fqmc::main(int argc, char ** argv) {

  formic::mpi::init(argc, argv);

  formic::start_timer("fqmc total");

  if (argc != 3)
    throw formic::Exception("formic::fqmc::main expects argc = 3  (program_name, input_file, output_file), but you gave argc = %i") % argc;

  // open the output file
  formic::open_output_file(argv[2]);

  // initialize the commands we will need
  formic::init_command_commands();
  formic::init_input_commands();
  formic::init_random_commands();
  formic::init_wfn_commands();
  formic::init_hamiltonian_commands();
  formic::init_hartree_fock_commands();
  formic::init_fqmc_commands();
  formic::init_rest_gem_pow_commands();
  formic::init_all_pair_jast_commands();

  // begin scope for input and all data objects
  {

    // prepare defualt input options, wavefunction, and hamiltonian
    formic::fqmc::Input userinp;
    formic::AllData data(userinp);

    // set random seed using current time
    formic::set_seed(std::time(0));

    // run user commands
    formic::run_text_commands(argv[1], data);

    //// print input options
    //formic::of << "------------------ Printing Input Options ------------------" << std::endl;
    //formic::of << std::endl;
    //formic::of << userinp.print_options();
    //formic::of << std::endl;
    //formic::of << "------------------- End of Input Options -------------------" << std::endl;
    //formic::of << std::endl;

  // end scope for input and all data objects
  }

  // delete vector storage
  if ( formic::mpi::rank() == 0 )
    formic::of << "deleting remaining vector storage" << std::endl << std::endl;
  formic::vector_garbage_collect();

  formic::stop_timer("fqmc total");
  if ( formic::mpi::rank() == 0 )
    formic::of << formic::print_timers();

  formic::close_output_file();

  formic::mpi::finalize();

  return EXIT_SUCCESS;

}
